//导入包
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.text.NumberFormat;
import javax.sound.sampled.*;
import java.io.*;
import java.util.concurrent.TimeUnit;

//创建Demo类继承JFrame类
public class Demo extends JFrame{
    /*  v1是第一个骰子的点数，v2是第二个骰子的点数，v3是第三个骰子的点数
        total是三个骰子的总点数  */
    private int v1, v2, v3, total;

    //flag 0表示没买的情况  1表示买大的情况  -1表示买小的情况
    private int flag;
    //cnt 记录的是赌大小的次数
    private int cnt = 0;
    //max 记录的是当前连胜次数
    private int max = 0;
    //big 记录的是开大的次数，small 记录的是开小的次数
    private int big = 0;
    private int small = 0;
    //won 记录胜的次数
    private int won = 0;
    //per 记录胜率
    private double per = 0.0;
    //BIG 记录的是买大的次数，SMALL 记录的是买小的次数
    private int BIG = 0;
    private int SMALL = 0;

    //c_music 记录的是播放与暂停音乐，当c_music为偶数时播放，当c_music为奇数时暂停
    //因为按一次就是奇数开始，再按一次就是偶数，所以重新播放
    private int c_music = 0;

    //创建三个标签存放骰子照片
    private JLabel Label_1 = new JLabel();
    private JLabel Label_2 = new JLabel();
    private JLabel Label_3 = new JLabel();
    //ok为true时启用线程，false时结束
    private boolean ok = false;

    //定义判断骰子点数的线程
    Thread thread = null;

    //设置窗体布局函数
    public Demo() {
        //新建一个JFrame类对象
        JFrame frame = new JFrame("欢迎使用摇骰子赌大小游戏");
        //创建一个窗口容器
        Container con = frame.getContentPane();
        //设置容器背景为与骰子图片相近颜色背景，利用取色器获取颜色的RGB值
        con.setBackground(new Color(245,245,245));
        con.setLayout(null);

        //设置标签1，2，3
        Label_1.setBounds(200,300,87,87);
        Label_1.setIcon(new ImageIcon("img/img1.png"));
        con.add(Label_1);
        Label_2.setBounds(350,300,87,87);
        Label_2.setIcon(new ImageIcon("img/img1.png"));
        con.add(Label_2);
        Label_3.setBounds(500,300,87,87);
        Label_3.setIcon(new ImageIcon("img/img1.png"));
        con.add(Label_3);

        //设置背景音乐
        Sound player = new Sound("src/music.wav");
        //循环播放
        player.start(true);

        //设置按钮
        JButton button_1 = new JButton();
        button_1.setText("买大");
        button_1.setFont(new Font("仿宋",1,20));
        button_1.setBackground(Color.white);
        button_1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ok = true;
                flag = 1;   //买大的情况
            }
        });
        button_1.setBounds(190,200,100,50);
        con.add(button_1);

        JButton button_2 = new JButton();
        button_2.setText("买小");
        button_2.setFont(new Font("仿宋",1,20));
        button_2.setBackground(Color.white);
        button_2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ok = true;
                flag = -1;  //买小的情况
            }
        });
        button_2.setBounds(345,200,100,50);
        con.add(button_2);

        JButton button_3 = new JButton();
        button_3.setText("开始");
        button_3.setFont(new Font("仿宋",1,20));
        button_3.setBackground(Color.white);
        button_3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ok = true;
                //flag不为0，已经点击买大或买小按钮的情况下，开始启动线程转动骰子
                if(flag != 0) {
                    if(thread == null) {
                        thread = new Thread(new DiceThread());
                        thread.start();
                    }
                } else if(flag == 0) {
                    //flag为0，此时玩家点击开始按钮，玩家并没有下注
                    JOptionPane.showMessageDialog(null," 您还没下注！！！请下注，选择买大还是买小。");
                }
            }
        });
        button_3.setBounds(190,430,100,50);
        con.add(button_3);

        JButton button_4 = new JButton();
        button_4.setText("结束");
        button_4.setFont(new Font("仿宋",1,20));
        button_4.setBackground(Color.white);
        //点击结束按钮，线程进入提示大小结果部分
        button_4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //标记变量变成false结束运行
                ok = false;
            }
        });
        button_4.setBounds(345,430,100,50);
        con.add(button_4);

        JButton button_5 = new JButton();
        button_5.setText("统计");
        button_5.setFont(new Font("仿宋",1,20));
        button_5.setBackground(Color.white);
        //统计按钮是纪录榜的内容，负责统计玩家游戏过程中的一些数据
        button_5.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //设置保留胜率的两位小数
                NumberFormat nf = NumberFormat.getNumberInstance();
                nf.setMaximumFractionDigits(2);
                //计算胜率
                per = won * 1.0/cnt;
                JOptionPane.showMessageDialog(null,
                        "      总游戏次数:"+cnt+"\n      开大的次数:"+big
                                +"\n      开小的次数:"+small+"\n      买大的次数:"+BIG
                                +"\n      买小的次数:"+SMALL+"\n      当前连胜次数:"+max
                                +"\n      获胜次数:"+won+"\n      胜率:"+nf.format(per*100)+"%"
                        ,"纪录榜",-1);
            }
        });
        button_5.setBounds(500,200,100,50);
        con.add(button_5);

        JButton button_6 = new JButton();
        button_6.setText("退出");
        button_6.setFont(new Font("仿宋",1,20));
        button_6.setBackground(Color.white);
        button_6.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //点击退出按钮关闭窗口
                frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING) );
            }
        });
        button_6.setBounds(500,430,100,50);
        con.add(button_6);

        JButton button_7 = new JButton();
        button_7.setIcon(new ImageIcon("img/music.jpeg"));
        button_7.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //点击禁音图标，c_music++
                c_music++;
                //奇数情况暂停播放
                if(c_music%2 != 0) {
                    player.stop();
                } else {
                    //偶数情况重新开始播放
                    player.start(true);
                }
            }
        });
        button_7.setBounds(50,50,55,55);
        con.add(button_7);

        frame.setSize(800,800);
        //使窗体居中显示
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    }

    private class DiceThread implements Runnable {
        //@Override
        public void run() {
            while(ok == true) {
                v1 = (int) (Math.random() * 6 + 1); //随机产生第一个骰子的点数
                v2 = (int) (Math.random() * 6 + 1); //随机产生第二个骰子的点数
                v3 = (int) (Math.random() * 6 + 1); //随机产生第三个骰子的点数
                //显示骰子的图片
                Label_1.setIcon(new ImageIcon("img/img" + v1 + ".png"));
                Label_2.setIcon(new ImageIcon("img/img" + v2 + ".png"));
                Label_3.setIcon(new ImageIcon("img/img" + v3 + ".png"));
                total = v1 + v2 + v3;   //统计总点数
                if (ok == false) {
                    if (flag == 1) {
                        BIG++;
                        if (total > 9) {
                            won++;
                            max++;
                            big++;
                            JOptionPane.showMessageDialog(null,
                                    "芜湖~~~玩家赢！！！\n点数是:" + total + "，大。");
                        } else {
                            max = 0;
                            small++;
                            JOptionPane.showMessageDialog(null,
                                    "可惜了~~~庄家赢！！！\n点数是:" + total + "，小。");
                        }
                    } else if (flag == -1) {
                        SMALL++;
                        if (total > 9) {
                            max = 0;
                            big++;
                            JOptionPane.showMessageDialog(null,
                                    "可惜了~~~庄家赢！！！\n点数是:" + total + "，大。");
                        } else {
                            won++;
                            max++;
                            small++;
                            JOptionPane.showMessageDialog(null,
                                    "芜湖~~~玩家赢！！！\n点数是:" + total + "，小。");
                        }
                    }
                    cnt++;           //游戏次数加一
                    flag = 0;        //下注状态置空
                    thread = null;   //线程置空
                    break;           //退出循环
                }
            }
        }
    }
    public static void main(String args[]) {
        //新建一个登录窗体类对象
        LoginFrame l = new LoginFrame();
    }
}

//音乐类
class Sound {
    private String musicPath;   //音频文件
    private volatile boolean run = true;  //记录音频是否播放
    private Thread mainThread;   //播放音频的任务线程

    private AudioInputStream audioStream;
    private AudioFormat audioFormat;
    private SourceDataLine sourceDataLine;

    public Sound(String musicPath) {
        this.musicPath = musicPath;
        prefetch();
    }

    //数据准备
    private void prefetch(){
        try{
            //获取音频输入流
            audioStream = AudioSystem.getAudioInputStream(new File(musicPath));
            //获取音频的编码对象
            audioFormat = audioStream.getFormat();
            //包装音频信息
            DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,
                    audioFormat,AudioSystem.NOT_SPECIFIED);
            //使用包装音频信息后的Info类创建源数据行，充当混频器的源
            sourceDataLine = (SourceDataLine)AudioSystem.getLine(dataLineInfo);

            sourceDataLine.open(audioFormat);
            sourceDataLine.start();

        }catch(UnsupportedAudioFileException ex){
            ex.printStackTrace();
        }catch(LineUnavailableException ex){
            ex.printStackTrace();
        }catch(IOException ex){
            ex.printStackTrace();
        }
    }

    //析构函数:关闭音频读取流和数据行
    protected void finalize() throws Throwable{
        super.finalize();
        sourceDataLine.drain();
        sourceDataLine.close();
        audioStream.close();
    }

    //播放音频:通过loop参数设置是否循环播放
    private void playMusic(boolean loop)throws InterruptedException {
        try{
            if(loop){
                while(true){
                    playMusic();
                }
            }else{
                playMusic();
                //清空数据行并关闭
                sourceDataLine.drain();
                sourceDataLine.close();
                audioStream.close();
            }

        }catch(IOException ex){
            ex.printStackTrace();
        }
    }

    private void playMusic(){
        try{
            synchronized(this){
                run = true;
            }
            //通过数据行读取音频数据流，发送到混音器;
            //数据流传输过程：AudioInputStream -> SourceDataLine;
            audioStream = AudioSystem.getAudioInputStream(new File(musicPath));
            int count;
            byte tempBuff[] = new byte[1024];

            while((count = audioStream.read(tempBuff,0,tempBuff.length)) != -1){
                synchronized(this){
                    while(!run)
                        wait();
                }
                sourceDataLine.write(tempBuff,0,count);
            }
        }catch(UnsupportedAudioFileException ex){
            ex.printStackTrace();
        }catch(IOException ex){
            ex.printStackTrace();
        }catch(InterruptedException ex){
            ex.printStackTrace();
        }
    }

    //暂停播放音频
    private void stopMusic(){
        synchronized(this){
            run = false;
            notifyAll();
        }
    }

    //继续播放音乐
    private void continueMusic(){
        synchronized(this){
            run = true;
            notifyAll();
        }
    }

    //外部调用控制方法:生成音频主线程；
    public void start(boolean loop){
        mainThread = new Thread(new Runnable(){
            public void run(){
                try {
                    playMusic(loop);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        mainThread.start();
    }

    //外部调用控制方法：暂停音频线程
    public void stop(){
        new Thread(new Runnable(){
            public void run(){
                stopMusic();
            }
        }).start();
    }

    //外部调用控制方法：继续音频线程
    public void continues(){
        new Thread(new Runnable(){
            public void run(){
                continueMusic();
            }
        }).start();
    }
}

//登录窗体类
class LoginFrame extends JFrame {
    //设置确定按钮和取消按钮,还有忘记密码按钮
    private static JButton bt1;
    private static JButton bt2;
    private static JButton bt3;
    //设置面板
    private static JLabel jl_1;
    //登陆窗口
    private static JFrame jf_1;
    //用户名
    private static JTextField text1;
    //密码
    private static JPasswordField text2;
    private static JLabel j1_admin;
    private static JLabel j1_password;

    public LoginFrame() {
        //利用j1_1来添加这些按钮，标签等等，可以使得密码在输入的时候隐藏加密
        jl_1 = new JLabel();
        jf_1 = new JFrame("登陆界面");
        jf_1.setSize(500, 500);
        jf_1.setLocationRelativeTo(null);

        j1_password = new JLabel("密码");
        j1_password.setBounds(20, 120, 60, 50);
        j1_password.setFont(new Font("仿宋", 1, 20));
        jl_1.add(j1_password);

        j1_admin = new JLabel("用户名");
        j1_admin.setBounds(20, 50, 80, 50);
        j1_admin.setFont(new Font("仿宋", 1, 20));
        jl_1.add(j1_admin);

        bt1 = new JButton("确定");
        bt1.setBounds(70, 250, 100, 50);
        bt1.setFont(new Font("仿宋", 1, 20));
        jl_1.add(bt1);

        bt2 = new JButton("取消");
        bt2.setBounds(200, 250, 100, 50);
        bt2.setFont(new Font("仿宋", 1, 20));
        jl_1.add(bt2);

        bt3 = new JButton("忘记密码");
        bt3.setBounds(330, 250, 130, 50);
        bt3.setFont(new Font("仿宋", 1, 20));
        jl_1.add(bt3);

        text1 = new JTextField("root");
        text1.setBounds(150, 50, 250, 50);
        text1.setFont(new Font("仿宋", 1, 20));
        jl_1.add(text1);

        text2 = new JPasswordField();
        text2.setBounds(150, 120, 250, 50);
        text2.setFont(new Font("仿宋", 1, 20));
        jl_1.add(text2);

        jf_1.add(jl_1);
        jf_1.setVisible(true);
        jf_1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //确定按钮的事件
        bt1.addActionListener(new ActionListener() {
            //@Override
            public void actionPerformed(ActionEvent e) {
                String admin = text1.getText();
                char[] password = text2.getPassword();
                String str = String.valueOf(password);
                //密码正确的情况，开始摇骰子游戏
                if (admin.equals("root") && str.equals("123456")) {
                    JOptionPane.showMessageDialog(null, "连接成功");
                    //隐藏登录窗口界面
                    jf_1.setVisible(false);
                    //显示游戏窗口界面
                    Demo dd = new Demo();
                } else {
                    //密码错误的情况，并把密码框重置为空
                    JOptionPane.showMessageDialog(null, "连接失败");
                    text2.setText(null);
                }
            }
        });

        //取消按钮的事件
        bt2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //点击退出按钮关闭窗口
                jf_1.dispatchEvent(new WindowEvent(jf_1, WindowEvent.WINDOW_CLOSING) );
            }
        });

        //忘记密码按钮的事件
        bt3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null, "又忘记密码了吧！！！这次可要记住了，密码是123456");
            }
        });
    }
}